import type { Ref } from 'vue';

import { ref, toRefs } from 'vue';

import { cloneDeep } from '@vben/utils';

import { ElLoading, ElMessage } from 'element-plus';

import { rasterServiceApi, vectorServiceApi } from '#/api';
import {
  barTootipCallback,
  mapSources,
  pieTootipCallback,
} from '#/assets/style';
import {
  ChartRender,
  Cluster,
  GradualValueRender,
  Heatmap,
  HierarchicalRender,
  IconLabel,
  ODRender,
  SingleValueRender,
  TextLabel,
  UniqueValueRender,
} from '#/assets/visualization-template';
import { usePublicStore, useSceneStore } from '#/store';
import {
  addCompositeLayer,
  applyLayerProperties,
  getDeckLayerConfig,
  getLastLayerOfTree,
  getPaintArrName,
  getTrueLayerPaintConfig,
  getVectorLayerConfig,
  isEqual,
  removeCompositeLayer,
} from '#/utils';

const publicStore = usePublicStore();
const sceneStore = useSceneStore();

// 保存图层的实际渲染参数到图层属性中，以便后续向地图中加载时恢复图层
const saveLayerParams = (renderOption: any, type: string, map: any) => {
  sceneStore.currentSceneConfig.layers.forEach((layer: any) => {
    if (layer.organizationType === 'singleLayer') {
      const { colorName, sizeName } = getPaintArrName(layer.type);
      if (layer.id === renderOption.layerId) {
        if (
          [
            'imageRaster',
            'multiBandRaster',
            'singleBandRaster',
            'singleValue',
          ].includes(type)
        ) {
          layer.paint = renderOption.paint;
          layer.layout = renderOption.layout;
        } else if (type === 'uniqueValue' || type === 'gradualValue') {
          layer.paint = renderOption.paint;
          layer.paint[colorName] = map.getPaintProperty(
            renderOption.layerId,
            colorName,
          );
          layer.layout = renderOption.layout;
        } else if (type === 'hierarchical') {
          layer.paint = renderOption.paint;
          if (renderOption.hierarchicalMethod === 'hierarchical_color') {
            layer.paint[colorName] = map.getPaintProperty(
              renderOption.layerId,
              colorName,
            );
          } else {
            layer.paint[sizeName] = map.getPaintProperty(
              renderOption.layerId,
              sizeName,
            );
          }
          layer.layout = renderOption.layout;
        }
      }
    } else {
      layer.layers.forEach((subLayer: any) => {
        if (subLayer.id === renderOption.layerId) {
          const { colorName, sizeName } = getPaintArrName(subLayer.type);
          if (subLayer.id === publicStore.RenderOptions.layer) {
            switch (type) {
              case 'gradualValue':
              case 'uniqueValue': {
                subLayer.paint = renderOption.paint;
                subLayer.paint[colorName] = map.getPaintProperty(
                  renderOption.layerId,
                  colorName,
                );
                subLayer.layout = renderOption.layout;

                break;
              }
              case 'hierarchical': {
                subLayer.paint = renderOption.paint;
                if (renderOption.hierarchicalMethod === 'hierarchical_color') {
                  subLayer.paint[colorName] = map.getPaintProperty(
                    renderOption.layerId,
                    colorName,
                  );
                } else {
                  subLayer.paint[sizeName] = map.getPaintProperty(
                    renderOption.layerId,
                    sizeName,
                  );
                }
                subLayer.layout = renderOption.layout;

                break;
              }
              case 'singleBandRaster':
              case 'singleValue': {
                subLayer.paint = renderOption.paint;
                subLayer.layout = renderOption.layout;

                break;
              }
              // No default
            }
          }
        }
      });
    }
  });
};
export const layerRenderUtil = () => {
  let map: any = null;
  let singleValueRender: any = null;
  let uniqueValueRender: any = null;
  let hierarchicalRender: any = null;
  let gradualValueRender: any = null;
  let heatMapRender: any = null;
  let cluster: any = null;
  let odRender: any = null;
  let textLabel: any = null;
  let iconLabel: any = null;
  let chartRender: any = null;
  const sceneLayersGroup: Ref<Array<any>> = ref([]);
  const sceneSourcesGroup: Ref<Array<any>> = ref([]);

  const initRender = (mapboxMap: any) => {
    map = mapboxMap;
    const { layers, sources } = toRefs(sceneStore.currentSceneConfig);
    sceneLayersGroup.value = layers?.value;
    sceneSourcesGroup.value = sources?.value;

    singleValueRender = new SingleValueRender(map);
    uniqueValueRender = new UniqueValueRender(map);
    hierarchicalRender = new HierarchicalRender(map);
    gradualValueRender = new GradualValueRender(map);
    chartRender = new ChartRender(map);
    heatMapRender = new Heatmap(map);
    cluster = new Cluster(map);
    odRender = new ODRender(map);
    textLabel = new TextLabel(map);
    iconLabel = new IconLabel(map);
  };
  const beforeRender = (type: string, layer: Ref<any>) => {
    //  渲染前先清除对应图层的echart实例和地图marker
    if (type !== 'textLabel') {
      chartRender.clearEchartInstantAndMarkers(layer.value.id);
    }
    // 初始化marker参数
    layer.value.markerParams = null;
  };
  const handleSingleValueRender = () => {
    const handlePointSingleValueRender = () => {
      const { point, layer, type } = publicStore.RenderOptions;
      if (point.outline === 'closed') {
        delete point.paint['circle-stroke-color'];
        delete point.paint['circle-stroke-width'];
        delete point.paint['circle-stroke-opacity'];
      } else {
        point.paint['circle-stroke-opacity'] /= 100;
      }
      point.paint['circle-opacity'] /= 100;
      point.paint['circle-blur'] /= 7;
      const pointSingleValueRenderOption = {
        layerId: layer,
        layerType: type,
        layout: point.layout,
        paint: point.paint,
      };
      singleValueRender.singleValueRenderEntry(pointSingleValueRenderOption);
      saveLayerParams(pointSingleValueRenderOption, 'singleValue', map);
    };

    const handlePolylineSingleValueRender = () => {
      const { line, layer, type } = publicStore.RenderOptions;
      line.paint['line-opacity'] /= 100;
      line.paint['line-blur'] *= 1.5;
      const polylineSingleValueRenderOption = {
        layerId: layer,
        layerType: type,
        layout: line.layout,
        paint: line.paint,
      };
      singleValueRender.singleValueRenderEntry(polylineSingleValueRenderOption);
      saveLayerParams(polylineSingleValueRenderOption, 'singleValue', map);
    };
    const handlePolygonSingleValueRender = () => {
      const { polygon, layer, type } = publicStore.RenderOptions;
      polygon.paint['fill-opacity'] /= 100;
      const polygonSingleRenderOption = {
        layerId: layer,
        layerType: type,
        layout: polygon.layout,
        paint: polygon.paint,
      };
      singleValueRender.singleValueRenderEntry(polygonSingleRenderOption);
      saveLayerParams(polygonSingleRenderOption, 'singleValue', map);
    };
    return {
      handlePointSingleValueRender,
      handlePolylineSingleValueRender,
      handlePolygonSingleValueRender,
    };
  };

  const handleUniqueValueRender = () => {
    const handlePointUniqueValueRender = () => {
      const { point, layer, type, renderField, colorRamp, uniqueValues } =
        publicStore.RenderOptions;
      if (point.outline === 'closed') {
        delete point.paint['circle-stroke-color'];
        delete point.paint['circle-stroke-width'];
        delete point.paint['circle-stroke-opacity'];
      } else {
        point.paint['circle-stroke-opacity'] /= 100;
      }
      point.paint['circle-opacity'] /= 100;
      point.paint['circle-blur'] /= 7;
      const pointUniqueValueRenderOption = {
        layerId: layer,
        layerType: type,
        renderField,
        colorRamp,
        uniqueValues,
        layout: point.layout,
        paint: point.paint,
      };
      uniqueValueRender.uniqueValueRenderEntry(pointUniqueValueRenderOption);
      saveLayerParams(pointUniqueValueRenderOption, 'uniqueValue', map);
    };

    const handlePolylineUniqueValueRender = () => {
      const { line, layer, type, renderField, colorRamp, uniqueValues } =
        publicStore.RenderOptions;
      line.paint['line-opacity'] /= 100;
      line.paint['line-blur'] *= 1.5;
      const polylineUniqueValueRenderOption = {
        layerId: layer,
        layerType: type,
        renderField,
        uniqueValues,
        colorRamp,
        layout: line.layout,
        paint: line.paint,
      };
      uniqueValueRender.uniqueValueRenderEntry(polylineUniqueValueRenderOption);
      saveLayerParams(polylineUniqueValueRenderOption, 'uniqueValue', map);
    };

    const handlePolygonUniqueValueRender = () => {
      const { polygon, layer, type, renderField, colorRamp, uniqueValues } =
        publicStore.RenderOptions;
      polygon.paint['fill-opacity'] /= 100;
      const polygonUniqueValueRenderOption = {
        layerId: layer,
        layerType: type,
        renderField,
        uniqueValues,
        colorRamp,
        layout: polygon.layout,
        paint: polygon.paint,
      };
      uniqueValueRender.uniqueValueRenderEntry(polygonUniqueValueRenderOption);
      saveLayerParams(polygonUniqueValueRenderOption, 'uniqueValue', map);
    };
    return {
      handlePointUniqueValueRender,
      handlePolylineUniqueValueRender,
      handlePolygonUniqueValueRender,
    };
  };

  const handleHierarchicalRender = () => {
    const handlePointHierarchicalRender = () => {
      const {
        point,
        layer,
        type,
        renderField,
        colorRamp,
        uniqueValues,
        level,
        hierarchicalMethod,
        radiusRange,
      } = publicStore.RenderOptions;
      if (point.outline === 'closed') {
        // 为了喂给大模型完整的属性，暂时先删除
        delete point.paint['circle-stroke-color'];
        delete point.paint['circle-stroke-width'];
        delete point.paint['circle-stroke-opacity'];
      } else {
        point.paint['circle-stroke-opacity'] /= 100;
      }
      point.paint['circle-opacity'] /= 100;
      point.paint['circle-blur'] /= 7;
      const pointHierarchicalRenderOption = {
        layerId: layer,
        layerType: type,
        renderField,
        colorRamp,
        uniqueValues,
        layout: point.layout,
        paint: point.paint,
        level,
        hierarchicalMethod,
        circleRadiusRange: radiusRange,
      };

      hierarchicalRender.hierarchicalRenderEntry(pointHierarchicalRenderOption);

      saveLayerParams(pointHierarchicalRenderOption, 'hierarchical', map);
    };
    const handlePolylineHierarchicalRender = () => {
      const {
        line,
        layer,
        type,
        renderField,
        colorRamp,
        uniqueValues,
        level,
        hierarchicalMethod,
        radiusRange,
      } = publicStore.RenderOptions;
      line.paint['line-opacity'] /= 100;
      line.paint['line-blur'] *= 1.5;
      const polylineHierarchicalRenderOption = {
        layerId: layer,
        layerType: type,
        renderField,
        colorRamp,
        uniqueValues,
        layout: line.layout,
        paint: line.paint,
        level,
        hierarchicalMethod,
        lineWidthRange: radiusRange,
      };
      hierarchicalRender.hierarchicalRenderEntry(
        polylineHierarchicalRenderOption,
      );
      saveLayerParams(polylineHierarchicalRenderOption, 'hierarchical', map);
    };
    const handlePolygonHierarchicalRender = () => {
      const {
        polygon,
        layer,
        type,
        renderField,
        colorRamp,
        uniqueValues,
        level,
        hierarchicalMethod,
      } = publicStore.RenderOptions;
      polygon.paint['fill-opacity'] /= 100;
      const polygonHierarchicalRenderOption = {
        layerId: layer,
        layerType: type,
        renderField,
        uniqueValues,
        colorRamp,
        level,
        layout: polygon.layout,
        paint: polygon.paint,
        hierarchicalMethod,
      };
      hierarchicalRender.hierarchicalRenderEntry(
        polygonHierarchicalRenderOption,
      );
      saveLayerParams(polygonHierarchicalRenderOption, 'hierarchical', map);
    };
    return {
      handlePointHierarchicalRender,
      handlePolylineHierarchicalRender,
      handlePolygonHierarchicalRender,
    };
  };

  const handleGradualValueRender = () => {
    const handlePointGradualValueRender = () => {
      const { point, layer, type, renderField, colorRamp, uniqueValues } =
        publicStore.RenderOptions;
      if (point.outline === 'closed') {
        delete point.paint['circle-stroke-color'];
        delete point.paint['circle-stroke-width'];
        delete point.paint['circle-stroke-opacity'];
      } else {
        point.paint['circle-stroke-opacity'] /= 100;
      }
      point.paint['circle-opacity'] /= 100;
      point.paint['circle-blur'] /= 7;
      const pointGradualValueRenderOption = {
        layerId: layer,
        layerType: type,
        renderField,
        colorRamp,
        uniqueValues,
        layout: point.layout,
        paint: point.paint,
      };
      gradualValueRender.gradualValueRenderEntry(pointGradualValueRenderOption);
      saveLayerParams(pointGradualValueRenderOption, 'gradualValue', map);
    };
    const handlePolylineGradualValueRender = () => {
      const { line, layer, type, renderField, colorRamp, uniqueValues } =
        publicStore.RenderOptions;
      line.paint['line-opacity'] /= 100;
      line.paint['line-blur'] *= 1.5;
      const polylineGradualValueRenderOption = {
        layerId: layer,
        layerType: type,
        renderField,
        colorRamp,
        uniqueValues,
        layout: line.layout,
        paint: line.paint,
      };
      gradualValueRender.gradualValueRenderEntry(
        polylineGradualValueRenderOption,
      );
      saveLayerParams(polylineGradualValueRenderOption, 'gradualValue', map);
    };
    const handlePolygonGradualValueRender = () => {
      const { polygon, layer, type, renderField, colorRamp, uniqueValues } =
        publicStore.RenderOptions;
      polygon.paint['fill-opacity'] /= 100;
      const polygonGradualValueRenderOption = {
        layerId: layer,
        layerType: type,
        renderField,
        uniqueValues,
        colorRamp,
        layout: polygon.layout,
        paint: polygon.paint,
      };
      gradualValueRender.gradualValueRenderEntry(
        polygonGradualValueRenderOption,
      );
      saveLayerParams(polygonGradualValueRenderOption, 'gradualValue', map);
    };
    return {
      handlePointGradualValueRender,
      handlePolylineGradualValueRender,
      handlePolygonGradualValueRender,
    };
  };

  const handleHeatmapRender = () => {
    const heatmapOptions = publicStore.RenderOptions;
    const {
      layer,
      colorRamp,
      weightField,
      'heatmap-weight': heatmapWeight,
      keepingLayer,
      layerOptions,
      basedZoomOptions,
    } = heatmapOptions;
    const source = sceneSourcesGroup.value.find(
      (_source: any) => layer.source === _source.sourceId,
    );
    heatmapOptions.mapLayer = getVectorLayerConfig(
      source,
      heatmapOptions.layer.name,
      'heatmap',
    );
    const heatmapRes = heatMapRender.heatMapRender2(heatmapOptions);
    if (heatmapRes.status === 'error') {
      ElMessage.error(heatmapRes.message);
    } else {
      heatmapRes.data.renderType = ['StyleMapping', 'heatMap'];
      heatmapRes.data.renderParams = {
        colorRamp,
        weightField,
        'heatmap-weight': heatmapWeight,
        keepingLayer,
        paint: layerOptions.paint,
        zoomRange: basedZoomOptions.zoomRange,
      };

      const lastLayer = getLastLayerOfTree(
        heatmapOptions.layer.id,
        cloneDeep(sceneStore.currentSceneConfig.layers),
      );
      if (lastLayer) {
        map.addLayer(heatmapRes.data, lastLayer.id);
      } else {
        map.addLayer(heatmapRes.data);
      }
      for (let i = 0; i < sceneStore.currentSceneConfig.layers.length; i++) {
        if (
          sceneStore.currentSceneConfig.layers[i].organizationType ===
          'groupLayer'
        ) {
          // 如果当前元素是图层组数组元素
          const index = sceneStore.currentSceneConfig.layers[
            i
          ].layers.findIndex(
            (item: any) => item.id === heatmapOptions.layer.id,
          );
          if (index !== -1) {
            // 找到目标图层
            if (index === 0) {
              sceneStore.currentSceneConfig.layers[i].layers.unshift(
                heatmapRes.data,
              );
            } else {
              sceneStore.currentSceneConfig.layers[i].layers.splice(
                index,
                0,
                heatmapRes.data,
              );
            }
            // 删除原图层
            if (!heatmapOptions.keepingLayer) {
              map.removeLayer(heatmapOptions.layer.id);
              sceneStore.currentSceneConfig.layers[i].layers.splice(
                index + 1,
                1,
              );
            }
            return;
          }
        } else if (
          sceneStore.currentSceneConfig.layers[i].id === heatmapOptions.layer.id
        ) {
          // 如果当前元素是单图层元素，且等于目标元素
          if (i === 0) {
            sceneStore.currentSceneConfig.layers.unshift(heatmapRes.data);
          } else {
            sceneStore.currentSceneConfig.layers.splice(i, 0, heatmapRes.data);
          }
          // 删除原图层
          if (!heatmapOptions.keepingLayer) {
            const islayerExist = map.getLayer(heatmapOptions.layer.id);

            // bug,图层重复叠加
            if (islayerExist) {
              map.removeLayer(heatmapOptions.layer.id);
              sceneStore.currentSceneConfig.layers.splice(i + 1, 1);
            }
          }
          return;
        }
      }
    }
  };

  const handleClusterRender = () => {
    // 用于记录最原始的面板参数
    const clusterOptions = cloneDeep(publicStore.RenderOptions);
    const { noneClusterLayerOptions } = publicStore.RenderOptions;

    // 用于渲染的参数
    noneClusterLayerOptions.paint['circle-opacity'] /= 100;
    noneClusterLayerOptions.paint['circle-blur'] /= 7;
    noneClusterLayerOptions.paint['circle-stroke-opacity'] /= 100;
    if (publicStore.RenderOptions.isCircleOpenOutline === 'closed') {
      delete publicStore.RenderOptions.isCircleOpenOutline;
      delete noneClusterLayerOptions.paint['circle-stroke-color'];
      delete noneClusterLayerOptions.paint['circle-stroke-opacity'];
      delete noneClusterLayerOptions.paint['circle-stroke-width'];
    }

    let source = sceneSourcesGroup.value.find(
      (_source: any) =>
        publicStore.RenderOptions.layer.source === _source.sourceId,
    );
    publicStore.RenderOptions.mapLayer = getVectorLayerConfig(
      source,
      publicStore.RenderOptions.layer.name,
      'cluster',
    );
    // 新生成的源
    source = cloneDeep(source); // 深拷贝去除响应式
    // 如果不是第一次生成聚合图,就不用再改源的名称和id
    if (publicStore.RenderOptions.layer.renderType[1] !== 'cluster') {
      source.sourceName += '_cluster';
      source.sourceId += '_cluster';
    }
    source.clusterOptions = {
      clusterMaxZoom: publicStore.RenderOptions.clusterMaxZoom,
      clusterRadius: publicStore.RenderOptions.clusterRadius,
    };
    // 如果不是第一次,需要先删除再添加
    if (publicStore.RenderOptions.layer.renderType[1] === 'cluster') {
      sceneStore.currentSceneConfig.sources =
        sceneStore.currentSceneConfig.sources.filter(
          (item: any) => item.sourceId !== source.sourceId,
        );
    }
    sceneStore.currentSceneConfig.sources.unshift(source);

    publicStore.RenderOptions.mapLayer.source = source;

    // 删除原图层
    if (!clusterOptions.keepingLayer) {
      removeCompositeLayer(clusterOptions.layer, map);
    }
    const layers = cluster.clusterRender(publicStore.RenderOptions)
      .data as Array<any>;
    // 将聚合图层作为主图层
    layers[0].renderType = ['StyleMapping', 'cluster'];
    // 剩下两个作为附属图层
    layers[0].clusterLayers =
      layers.length === 3 ? [layers[1], layers[2]] : [layers[1]];
    layers[0].renderParams = {
      clusterRadius: clusterOptions.clusterRadius,
      clusterMaxZoom: clusterOptions.clusterMaxZoom,
      clusterRules: clusterOptions.clusterRules,
      keepingLayer: clusterOptions.keepingLayer,
      isSymbolText: clusterOptions.isSymbolText,
      symbolText: clusterOptions.symbolText,
      isCircleOpenOutline: clusterOptions.isCircleOpenOutline,
      noneClusterLayerOptions_paint:
        clusterOptions.noneClusterLayerOptions.paint,
    };

    const lastLayer = getLastLayerOfTree(
      clusterOptions.layer.id,
      cloneDeep(sceneStore.currentSceneConfig.layers),
    );

    layers.forEach((layer: any) => {
      if (lastLayer) {
        map.addLayer(layer, lastLayer.id);
      } else {
        map.addLayer(layer);
      }
    });
    ElMessage.success('聚合图渲染成功！');
    // 更新图层目录
    for (let i = 0; i < sceneStore.currentSceneConfig.layers.length; i++) {
      if (
        sceneStore.currentSceneConfig.layers[i].organizationType ===
        'groupLayer'
      ) {
        // 如果当前元素是图层组数组元素
        const index = sceneStore.currentSceneConfig.layers[i].layers.findIndex(
          (item: any) => item.id === clusterOptions.layer.id,
        );
        if (index !== -1) {
          // 找到目标图层
          if (index === 0) {
            sceneStore.currentSceneConfig.layers[i].layers.unshift(layers[0]);
          } else {
            sceneStore.currentSceneConfig.layers[i].layers.splice(
              index,
              0,
              layers[0],
            );
          }
          // 删除原图层
          if (!clusterOptions.keepingLayer) {
            sceneStore.currentSceneConfig.layers[i].layers.splice(index + 1, 1);
          }
          return;
        }
      } else if (
        sceneStore.currentSceneConfig.layers[i].id === clusterOptions.layer.id
      ) {
        // 如果当前元素是单图层元素，且等于目标元素
        if (i === 0) {
          sceneStore.currentSceneConfig.layers.unshift(layers[0]);
        } else {
          sceneStore.currentSceneConfig.layers.splice(i, 0, layers[0]);
        }

        // 删除原图层
        if (!clusterOptions.keepingLayer) {
          sceneStore.currentSceneConfig.layers.splice(i + 1, 1);
        }
        return;
      }
    }
  };

  const handleTextLabelRender = () => {
    if (publicStore.LabelOptions.layout['symbol-placement'] !== 'line') {
      delete publicStore.LabelOptions.layout['symbol-spacing'];
    }
    publicStore.LabelOptions.paint['text-opacity'] /= 100;
    const textLabelOptions = publicStore.LabelOptions;

    const source = sceneSourcesGroup.value.find(
      (_source: any) => textLabelOptions.layer.source === _source.sourceId,
    );

    // 如果该图层已有注记图层，则只修改layout和paint
    if (textLabelOptions.layer.labelLayer) {
      textLabel.textLabelRender(textLabelOptions);
      textLabelOptions.layer.labelLayer.layout = textLabelOptions.layout;
      textLabelOptions.layer.labelLayer.paint = textLabelOptions.paint;
      textLabelOptions.layer.labelLayer.layout['text-field'] = [
        'get',
        textLabelOptions.renderField,
      ];
    }
    // 否则创建新图层
    else {
      const textLabelLayer = getVectorLayerConfig(
        source,
        textLabelOptions.layer.name,
        'textLabel',
      );
      textLabelLayer.layout = textLabelOptions.layout;
      textLabelLayer.layout['text-field'] = [
        'get',
        textLabelOptions.renderField,
      ];
      textLabelLayer.paint = textLabelOptions.paint;
      // 如果有图标图层，则插入到图标图层之前（保持字体注记图层在图标图层之前）
      if (textLabelOptions.layer.iconLayer) {
        map.addLayer(textLabelLayer, textLabelOptions.layer.iconLayer.id);
        map.moveLayer(textLabelOptions.layer.iconLayer.id, textLabelLayer.id);
      } else {
        const lastLayer = getLastLayerOfTree(
          textLabelOptions.layer.id,
          cloneDeep(sceneStore.currentSceneConfig.layers),
        );
        if (lastLayer) {
          map.addLayer(textLabelLayer, lastLayer.id);
        } else {
          map.addLayer(textLabelLayer);
        }
      }
      textLabelOptions.layer.labelLayer = textLabelLayer;
    }
  };

  const handleIconLabelRender = () => {
    if (publicStore.LabelOptions.layout['symbol-placement'] !== 'line') {
      delete publicStore.LabelOptions.layout['symbol-spacing'];
    }
    publicStore.LabelOptions.paint['icon-opacity'] /= 100;
    const iconLabelOptions = publicStore.LabelOptions;
    const source = sceneSourcesGroup.value.find(
      (_source: any) => iconLabelOptions.layer.source === _source.sourceId,
    );

    // 如果该图层已有图标图层，则只修改layout和paint
    if (iconLabelOptions.layer.iconLayer) {
      iconLabel.iconLabelRender(iconLabelOptions);
      iconLabelOptions.layer.iconLayer.layout = iconLabelOptions.layout;
      iconLabelOptions.layer.iconLayer.paint = iconLabelOptions.paint;
    }
    // 否则创建新图层
    else {
      const iconLabelLayer = getVectorLayerConfig(
        source,
        iconLabelOptions.layer.name,
        'iconLabel',
      );
      iconLabelLayer.layout = iconLabelOptions.layout;
      iconLabelLayer.paint = iconLabelOptions.paint;

      // 如果有字体注记图层，则插入到字体注记图层之后（保持字体注记图层在图标图层之上）
      if (iconLabelOptions.layer.labelLayer) {
        map.addLayer(iconLabelLayer, iconLabelOptions.layer.labelLayer.id);
      } else {
        const lastLayer = getLastLayerOfTree(
          iconLabelOptions.layer.id,
          cloneDeep(sceneStore.currentSceneConfig.layers),
        );
        if (lastLayer) {
          map.addLayer(iconLabelLayer, lastLayer.id);
        } else {
          map.addLayer(iconLabelLayer);
        }
      }
      iconLabelOptions.layer.iconLayer = iconLabelLayer;
    }
  };

  const handleImageRasterRender = async (layer: Ref<any>) => {
    // 解构出来的是引用类型，属于浅拷贝
    const { RenderOptions } = publicStore;

    layer.value.renderType = ['RasterMapping', 'imageRasterRender'];

    layer.value.renderParams = {
      paint: cloneDeep(RenderOptions.paint),
    };

    // publicStore.RenderOptions的变化会引起RenderOptions的变化，无需重新解构
    publicStore.RenderOptions.paint['raster-opacity'] /= 100;
    publicStore.RenderOptions.paint['raster-saturation'] /= 100;
    publicStore.RenderOptions.paint['raster-contrast'] /= 100;

    const { paint, layout } = RenderOptions;
    applyLayerProperties(map, layer.value.id, paint, layout);

    const Options = {
      layerId: RenderOptions.layer.id,
      ...RenderOptions,
    };
    //  保存到图层属性

    saveLayerParams(Options, 'imageRaster', map);
  };
  const handleSingleBandRasterRender = async (layer: Ref<any>) => {
    let isRenderInBackend = true;

    // 解构出来的是引用类型，属于浅拷贝
    const { RenderOptions } = publicStore;
    const { renderParams } = layer.value;

    // 判断重新渲染是否涉及后端渲染，减少渲染开销
    const isBandRampEqual =
      isEqual(RenderOptions.band, renderParams.band) &&
      isEqual(RenderOptions.ramp, renderParams.ramp);
    const isShadeEqual = isEqual(RenderOptions.isShade, renderParams.isShade);
    if (
      (isBandRampEqual && isShadeEqual && !RenderOptions.isShade) ||
      (isBandRampEqual &&
        isShadeEqual &&
        RenderOptions.isShade &&
        isEqual(RenderOptions.shadeParams, renderParams.shadeParams))
    ) {
      isRenderInBackend = false;
    }

    layer.value.renderType = ['RasterMapping', 'singleBandRasterRender'];

    layer.value.renderParams = {
      band: RenderOptions.band,
      ramp: RenderOptions.ramp,
      type: RenderOptions.type,
      paint: cloneDeep(RenderOptions.paint),
      isShade: RenderOptions.isShade,
      shadeParams: cloneDeep(RenderOptions.shadeParams),
    };

    // publicStore.RenderOptions的变化会引起RenderOptions的变化，无需重新解构
    publicStore.RenderOptions.paint['raster-opacity'] /= 100;
    publicStore.RenderOptions.paint['raster-saturation'] /= 100;
    publicStore.RenderOptions.paint['raster-contrast'] /= 100;

    const sceneLoading = ElLoading.service({
      lock: true,
      text: '渲染中...',
      background: 'rgba(0, 0, 0, 0.6)',
    });

    if (isRenderInBackend) {
      const source = sceneSourcesGroup.value.find(
        (_source: any) => RenderOptions.layer.source === _source.sourceId,
      );
      const imageSource = map.getSource(RenderOptions.layer.source);
      const changeColorMapDTO = {
        userId: sceneStore.editingScene.userId,
        rasterSId: RenderOptions.layer.source,
        sceneId: sceneStore.editingScene.sceneId,
        band: RenderOptions.band,
        colorMap: RenderOptions.ramp,
        shade: RenderOptions.isShade,
        shadeParams: RenderOptions.shadeParams,
      };
      const res = await rasterServiceApi.changeColorMap(changeColorMapDTO);
      if (res.code === '200') {
        imageSource.updateImage({
          url: `${source.url}?version=${Date.now()}`,
        });
        const { layer, paint, layout } = RenderOptions;
        applyLayerProperties(map, layer.id, paint, layout);
        ElMessage.success('渲染成功');
        sceneLoading.close();
      } else {
        ElMessage.error(res.message);
      }
    } else {
      const { layer, paint, layout } = RenderOptions;
      applyLayerProperties(map, layer.id, paint, layout);
      ElMessage.success('渲染成功');
      sceneLoading.close();
    }

    const Options = {
      layerId: RenderOptions.layer.id,
      ...RenderOptions,
    };
    //  保存到图层属性

    saveLayerParams(Options, 'singleBandRaster', map);
  };

  const handleMultiBandRasterRender = (layer: Ref<any>) => {
    let isRenderInBackend = true;

    layer.value.renderType = ['RasterMapping', 'multiBandRasterRender'];
    const { RenderOptions } = publicStore;
    const { renderParams } = layer.value;
    layer.value.renderParams = {
      bandList: RenderOptions.bandList,
      paint: cloneDeep(RenderOptions.paint),
    };

    // 判断重新渲染是否涉及后端渲染，减少渲染开销
    if (isEqual(RenderOptions.bandList, renderParams.bandList)) {
      isRenderInBackend = false;
    }

    RenderOptions.paint['raster-opacity'] /= 100;
    RenderOptions.paint['raster-saturation'] /= 100;
    RenderOptions.paint['raster-contrast'] /= 100;

    const sceneLoading = ElLoading.service({
      lock: true,
      text: '渲染中...',
      background: 'rgba(0, 0, 0, 0.6)',
    });

    if (isRenderInBackend) {
      const source = sceneSourcesGroup.value.find(
        (_source: any) => RenderOptions.layer.source === _source.sourceId,
      );
      const imageSource = map.getSource(RenderOptions.layer.source);
      const falseColorCompositeDTO = {
        userId: sceneStore.editingScene.userId,
        sceneId: sceneStore.editingScene.sceneId,
        rasterSId: RenderOptions.layer.source,
        bandList: RenderOptions.bandList,
      };
      rasterServiceApi
        .falseColorComposite(falseColorCompositeDTO)
        .then((res: any) => {
          if (res.code === '200') {
            imageSource.updateImage({
              url: `${source.url}?version=${Date.now()}`,
            });
            const { layer, paint, layout } = RenderOptions;
            applyLayerProperties(map, layer.id, paint, layout);
            ElMessage.success('渲染成功');
            sceneLoading.close();
          }
        });
    } else {
      const { layer, paint, layout } = RenderOptions;
      applyLayerProperties(map, layer.id, paint, layout);
      ElMessage.success('渲染成功');
      sceneLoading.close();
    }

    const Options = {
      layerId: RenderOptions.layer.id,
      ...RenderOptions,
    };
    //  保存到图层属性
    saveLayerParams(Options, 'multiBandRaster', map);
  };

  const handleODRender = () => {
    const ODOptions = publicStore.RenderOptions;
    const source = sceneSourcesGroup.value.find(
      (_source: any) => ODOptions.layer.source === _source.sourceId,
    );
    fetch(source.url)
      .then((res) => res.json())
      .then((data) => {
        const { features } = data;
        ODOptions.mapLayer = getDeckLayerConfig(
          features,
          ODOptions.layer.name,
          'OD',
        );
        ODOptions.mapLayer.props.source = source.sourceId;
        const ODLayer = odRender.ODRenderEntry(ODOptions).data;
        map.addLayer(ODLayer);
        // 取出相应的属性，自定义存储到场景的layerGroup中
        const layer = {
          id: ODLayer.props.id,
          name: ODLayer.props.name,
          layout: ODLayer.props.layout,
          source: ODLayer.props.source,
          type: 'Style-OD',
          // type: 'custom',
          organizationType: ODLayer.props.organizationType,
        };
        sceneStore.currentSceneConfig.layers.unshift(layer);
      });
  };

  // 区分渲染和恢复
  const handlePieRender = async (
    restore: boolean,
    renderOrRestoreOptions: any,
    currentLayer?: Ref<any>,
  ) => {
    const {
      layer,
      selectedFields,
      colorRamp,
      chartOptions,
      markerOptions: { chartWidth, chartHeight },
      background: { point, polygon },
    } = renderOrRestoreOptions;
    const features = await vectorServiceApi.getCenterAndAttrByFields(
      layer['source-layer'],
      selectedFields,
    );

    if (!restore && currentLayer) {
      currentLayer.value.renderType = ['ChartMapping', 'pie'];
      currentLayer.value.renderParams = {
        selectedFields,
        colorRamp,
        background: { point, polygon },
        markerOptions: { chartWidth, chartHeight },
        radius: chartOptions.series[0].radius,
        labelOptions: cloneDeep(chartOptions.series[0].label),
      };
      currentLayer.value.markerParams = cloneDeep(renderOrRestoreOptions);

      const { layout, paint } = layer.type === 'circle' ? point : polygon;
      applyLayerProperties(map, layer.id, paint, layout);

      const backgroundOptions = {
        layerId: layer.id,
        layerType: layer.type,
        layout,
        paint,
      };
      saveLayerParams(backgroundOptions, 'singleValue', map);
    } else {
      // 恢复回调函数
      chartOptions.tooltip.formatter = pieTootipCallback;
    }
    let renderOptions;
    for (const feature of features) {
      const data = Object.keys(feature)
        .filter((key) => key !== 'center')
        .map((key) => ({ value: feature[key], name: key })) as any;
      renderOptions = {
        coordinate: feature.center,
        colorRamp,
        chartOptions,
        dataOption: data,
        layerId: layer.id,
        chartHeight,
        chartWidth,
      };
      chartRender.addThematicEchartLayer('pie', renderOptions);
    }
  };

  const handleBarRender = async (
    restore: boolean,
    renderOrRestoreOptions: any,
    currentLayer?: Ref<any>,
  ) => {
    const {
      layer,
      selectedFields,
      colorRamp,
      chartOptions,
      seriesOptions: { barWidth, isLabelOpen, labelSize },
      markerOptions: { chartWidth, chartHeight },
      background: { point, polygon },
    } = renderOrRestoreOptions;
    const features = await vectorServiceApi.getCenterAndAttrByFields(
      layer['source-layer'],
      selectedFields,
    );
    if (!restore && currentLayer) {
      currentLayer.value.renderType = ['ChartMapping', 'bar'];
      currentLayer.value.renderParams = {
        selectedFields,
        colorRamp,
        background: { point, polygon },
        markerOptions: { chartWidth, chartHeight },
        seriesOptions: { barWidth, isLabelOpen, labelSize },
        barHeightParam: chartOptions.grid.top,
      };
      currentLayer.value.markerParams = cloneDeep(renderOrRestoreOptions);
      const { layout, paint } = layer.type === 'circle' ? point : polygon;
      applyLayerProperties(map, layer.id, paint, layout);
      const backgroundOptions = {
        layerId: layer.id,
        layerType: layer.type,
        layout,
        paint,
      };
      saveLayerParams(backgroundOptions, 'singleValue', map);
    } else {
      // 恢复回调函数
      chartOptions.tooltip.formatter = barTootipCallback(layer.name);
    }

    let renderOptions;
    for (const feature of features) {
      const keys = Object.keys(feature).filter((key) => key !== 'center');
      const seriesData = keys.map((key, index) => {
        const obj = {
          name: key,
          type: 'bar',
          barWidth: barWidth / 1.5,
          label: {
            show: isLabelOpen,
            position: 'top',
            fontSize: labelSize / 1.5,
          },
        } as any;
        if (index === keys.length - 1) {
          obj.barGap = '0%';
        }
        return obj;
      });
      const data = ['value'];
      keys.forEach((key) => {
        data.push(feature[key]);
      });
      renderOptions = {
        coordinate: feature.center,
        colorRamp,
        chartOptions,
        dataOption: data,
        seriesOption: seriesData,
        layerId: layer.id,
        chartHeight,
        chartWidth,
      };
      chartRender.addThematicEchartLayer('bar', renderOptions);
    }
  };
  const handleSingleValueRendertry = (layer: Ref<any>) => {
    const {
      handlePointSingleValueRender,
      handlePolylineSingleValueRender,
      handlePolygonSingleValueRender,
    } = handleSingleValueRender();
    const { point, line, polygon, type } = publicStore.RenderOptions;

    layer.value.renderType = ['BasicMapping', 'singleValueRender'];

    if (type === 'circle') {
      layer.value.renderParams = cloneDeep(point);
      handlePointSingleValueRender();
    } else if (type === 'line') {
      layer.value.renderParams = cloneDeep(line);
      handlePolylineSingleValueRender();
    } else {
      layer.value.renderParams = cloneDeep(polygon);
      handlePolygonSingleValueRender();
    }
  };

  const handleUniqueValueRenderEntry = (layer: Ref<any>) => {
    const {
      handlePointUniqueValueRender,
      handlePolylineUniqueValueRender,
      handlePolygonUniqueValueRender,
    } = handleUniqueValueRender();
    const {
      point,
      line,
      polygon,
      type,
      currentLegendList,
      renderField,
      colorRamp,
    } = publicStore.RenderOptions;
    layer.value.renderType = ['BasicMapping', 'uniqueValueRender'];
    layer.value.renderParams = {
      currentLegendList,
      renderField,
      colorRamp,
      renderParam: {},
    };
    if (type === 'circle') {
      layer.value.renderParams.renderParam = cloneDeep(point);
      handlePointUniqueValueRender();
    } else if (type === 'line') {
      layer.value.renderParams.renderParam = cloneDeep(line);
      handlePolylineUniqueValueRender();
    } else {
      layer.value.renderParams.renderParam = cloneDeep(polygon);
      handlePolygonUniqueValueRender();
    }
  };

  const handlehierarchicalRenderEntry = (layer: Ref<any>) => {
    const {
      handlePointHierarchicalRender,
      handlePolylineHierarchicalRender,
      handlePolygonHierarchicalRender,
    } = handleHierarchicalRender();
    const {
      point,
      line,
      polygon,
      type,
      currentLegendList,
      renderField,
      colorRamp,
      level,
      hierarchicalMethod,
      radiusRange,
      uniqueValues,
    } = publicStore.RenderOptions;
    layer.value.renderType = ['BasicMapping', 'hierarchicalRender'];
    layer.value.renderParams = {
      currentLegendList,
      renderField,
      colorRamp,
      renderParam: {},
      level,
      hierarchicalMethod,
      radiusRange,
      uniqueValues,
    };
    if (type === 'circle') {
      layer.value.renderParams.renderParam = cloneDeep(point);
      handlePointHierarchicalRender();
    } else if (type === 'line') {
      layer.value.renderParams.renderParam = cloneDeep(line);
      handlePolylineHierarchicalRender();
    } else {
      layer.value.renderParams.renderParam = cloneDeep(polygon);
      handlePolygonHierarchicalRender();
    }
  };

  const handleGradualValueRenderEntry = (layer: Ref<any>) => {
    const {
      handlePointGradualValueRender,
      handlePolylineGradualValueRender,
      handlePolygonGradualValueRender,
    } = handleGradualValueRender();
    const {
      point,
      line,
      polygon,
      type,
      currentLegendList,
      renderField,
      colorRamp,
      sort,
    } = publicStore.RenderOptions;
    layer.value.renderType = ['BasicMapping', 'gradualValueRender'];
    layer.value.renderParams = {
      currentLegendList,
      renderField,
      colorRamp,
      sort,
      renderParam: {},
    };
    if (type === 'circle') {
      layer.value.renderParams.renderParam = cloneDeep(point);
      handlePointGradualValueRender();
    } else if (type === 'line') {
      layer.value.renderParams.renderParam = cloneDeep(line);
      handlePolylineGradualValueRender();
    } else {
      layer.value.renderParams.renderParam = cloneDeep(polygon);
      handlePolygonGradualValueRender();
    }
  };

  const handlePieRenderEntry = (layer: Ref<any>) => {
    const { RenderOptions } = publicStore;
    handlePieRender(false, RenderOptions, layer);
  };

  const handleBarRenderEntry = (layer: Ref<any>) => {
    const { RenderOptions } = publicStore;
    handleBarRender(false, RenderOptions, layer);
  };
  const renderEntry = async (type: string, layer: Ref<any>) => {
    beforeRender(type, layer);
    switch (type) {
      case 'bar': {
        handleBarRenderEntry(layer);
        break;
      }
      case 'cluster': {
        handleClusterRender();
        break;
      }
      case 'gradualValueRender': {
        handleGradualValueRenderEntry(layer);
        break;
      }
      case 'heatMap': {
        handleHeatmapRender();
        break;
      }
      case 'hierarchicalRender': {
        handlehierarchicalRenderEntry(layer);
        break;
      }
      case 'iconLabel': {
        handleIconLabelRender();
        break;
      }
      case 'imageRasterRender': {
        handleImageRasterRender(layer);
        break;
      }
      case 'multiBandRasterRender': {
        handleMultiBandRasterRender(layer);
        break;
      }
      case 'OD': {
        handleODRender();
        break;
      }
      case 'pie': {
        handlePieRenderEntry(layer);
        break;
      }
      case 'singleBandRasterRender': {
        await handleSingleBandRasterRender(layer);
        break;
      }
      case 'singleValueRender': {
        handleSingleValueRendertry(layer);
        break;
      }
      case 'textLabel': {
        handleTextLabelRender();
        break;
      }
      case 'uniqueValueRender': {
        handleUniqueValueRenderEntry(layer);
        break;
      }
      default: {
        break;
      }
    }
    // 清空全局options
    publicStore.setRenderOptions({});
    publicStore.setLabelOptions({});
  };

  // 设置地图图层的显隐
  const setMapLayerVisibility = (layerItem: any, val: 'none' | 'visible') => {
    map.setLayoutProperty(layerItem.id, 'visibility', val);
    // 注记层
    if (layerItem.labelLayer) {
      map.setLayoutProperty(layerItem.labelLayer.id, 'visibility', val);
    }
    // 图标层
    if (layerItem.iconLayer) {
      map.setLayoutProperty(layerItem.iconLayer.id, 'visibility', val);
    }
    // 聚合层
    if (layerItem.clusterLayers) {
      layerItem.clusterLayers.forEach((layer: any) => {
        map.setLayoutProperty(layer.id, 'visibility', val);
      });
    }
    // marker层
    if (layerItem.markerParams) {
      if (val === 'visible') {
        if (layerItem.renderType[1] === 'pie') {
          handlePieRender(true, layerItem.markerParams);
        } else {
          handleBarRender(true, layerItem.markerParams);
        }
      } else {
        chartRender.clearEchartInstantAndMarkers(layerItem.id);
      }
    }
  };
  // 设置图层(属性）的显隐状态
  const setLayerVisibility = (
    layer: any,
    layerItem: any,
    val: 'none' | 'visible',
  ) => {
    layer.layout.visibility = val;
    // 注记层
    if (layerItem.labelLayer) {
      layer.labelLayer.layout.visibility = val;
    }
    // 图标层
    if (layerItem.iconLayer) {
      layer.iconLayer.layout.visibility = val;
    }
    // 聚合层
    if (layerItem.clusterLayers) {
      layer.clusterLayers.forEach((subLayer: any) => {
        subLayer.layout.visibility = val;
      });
    }
  };
  const handleSetLayerVisibility = (layerItem: any, val: any) => {
    if (layerItem.organizationType === 'singleLayer') {
      setMapLayerVisibility(layerItem, val);
      // 更新到store
      sceneStore.currentSceneConfig.layers.some((layer: any) => {
        const targetLayer =
          layer.organizationType === 'singleLayer'
            ? layer
            : layer.layers.find(
                (subLayer: any) => subLayer.id === layerItem.id,
              );

        // 如果找到目标层，设置可见性并停止遍历
        if (targetLayer && targetLayer.id === layerItem.id) {
          setLayerVisibility(targetLayer, layerItem, val);
          return true; // 找到目标后，退出遍历
        }
        return false; // 继续遍历
      });
    } else {
      layerItem.layers.forEach((subLayerItem: any) => {
        setMapLayerVisibility(subLayerItem, val);
      });
      // 更新到store
      const storeGroupLayer = sceneStore.currentSceneConfig.layers.find(
        (layer: any) => layer.id === layerItem.id,
      );
      storeGroupLayer.layers.forEach((subLayer: any, index: number) => {
        setLayerVisibility(subLayer, layerItem.layers[index], val);
      });
    }
  };

  const loadLayersToMap = () => {
    return new Promise((resolve) => {
      for (let i = sceneLayersGroup.value.length - 1; i >= 0; i--) {
        if (sceneLayersGroup.value[i].organizationType === 'singleLayer') {
          const source = map.getSource(sceneLayersGroup.value[i].source);

          if (source) {
            addCompositeLayer(
              getTrueLayerPaintConfig(sceneLayersGroup.value[i]),
              map,
            );
            if (
              sceneLayersGroup.value[i].markerParams &&
              sceneLayersGroup.value[i].layout.visibility === 'visible'
            ) {
              if (sceneLayersGroup.value[i].renderType[1] === 'pie') {
                handlePieRender(true, sceneLayersGroup.value[i].markerParams);
              } else {
                handleBarRender(true, sceneLayersGroup.value[i].markerParams);
              }
            }
          } else {
            ElMessage.info(
              `图层${sceneLayersGroup.value[i].name}对应的数据源不存在`,
            );
          }
        } else {
          for (
            let j = sceneLayersGroup.value[i].layers.length - 1;
            j >= 0;
            j--
          ) {
            // 补充添加底图源
            if (sceneLayersGroup.value[i].layers[j].id === 'vec_annotate') {
              map.addSource('vec_mapSource_annotate', mapSources.vectorMap[1]);
            }
            if (sceneLayersGroup.value[i].layers[j].id === 'vec_mapLayer') {
              map.addSource('vec_mapSource_map', mapSources.vectorMap[0]);
            }
            if (sceneLayersGroup.value[i].layers[j].id === 'img_annotate') {
              map.addSource('img_mapSource_annotate', mapSources.imageMap[1]);
            }
            if (sceneLayersGroup.value[i].layers[j].id === 'img_mapLayer') {
              map.addSource('img_mapSource_map', mapSources.imageMap[0]);
            }
            if (sceneLayersGroup.value[i].layers[j].id === 'ter_annotate') {
              map.addSource('ter_mapSource_annotate', mapSources.terrainMap[1]);
            }
            if (sceneLayersGroup.value[i].layers[j].id === 'ter_mapLayer') {
              map.addSource('ter_mapSource_map', mapSources.terrainMap[0]);
            }
            const source = map.getSource(
              sceneLayersGroup.value[i].layers[j].source,
            );
            if (source) {
              addCompositeLayer(
                getTrueLayerPaintConfig(sceneLayersGroup.value[i].layers[j]),
                map,
              );
              if (
                sceneLayersGroup.value[i].layers[j].markerParams &&
                sceneLayersGroup.value[i].layers[j].layout.visibility ===
                  'visible'
              ) {
                if (sceneLayersGroup.value[i].renderType[1] === 'pie') {
                  handlePieRender(true, sceneLayersGroup.value[i].markerParams);
                } else {
                  handleBarRender(true, sceneLayersGroup.value[i].markerParams);
                }
              }
            } else {
              ElMessage.info(
                `图层${
                  sceneLayersGroup.value[i].layers[j].name
                }对应的数据源不存在`,
              );
            }
          }
        }
      }
      resolve('加载图层完毕');
    });
  };
  return { initRender, renderEntry, handleSetLayerVisibility, loadLayersToMap };
};
